import { dynamicCSS } from './dynamicCss.js';
import { verify } from './verify.js';
import { rules } from './rules.js';
import { optionSide } from './optionSide.js';

dynamicCSS('/css/radio.css');


var radioItem = function (key, data, parent) {
    this.parent = parent;
    this.data = data;
    this.name = data[key];
    var html = '';
    html += '<div class="form_radio_Item">';
    html += '   <span class="form_radio_choose"></span>';
    html += '   <div class="form_radio_name">' + this.name + '</div>';
    html += '</div>';
    this.html = $(html);
    this._element = this.html.find('.form_radio_choose');
    this.selectStutas = false;
    var _this = this;
    this.html.unbind().bind('click', function () {
        _this.parent.change(_this);
    });
};
radioItem.prototype = {
    constructor: this,
    select: function () {
        this.valueData = true;
        this._element.addClass('active');
        this.html.unbind();
    },
    unSelect: function () {
        var _this = this;
        this._element.removeClass('active');
        this.html.unbind().bind('click', function () {
            _this.parent.change(_this);
        });
    },
};

var radio = function (options, layout) {
    var _this = this;
    this.layout = layout;

    this.options = $.extend({}, {
        className: '', // 自定义元素样式
        verify: {  // 验证判断组
            text: '',
            rules: []
        },
        showKey: 'label', // 根据子对象的数据Key值进行显示
        setKey: 'value', // 根据子对象的数据Key值进行赋值
        getKey: 'setKey', // 根据子对象的数据Key值进行取值
        "default": null, // 默认值
        readonly: false, // 是否只读
        size: 'normal', // 默认大小
        data: [], // 数据来源
        onChange: function () { }, // 当值发生改变时,调用方法
        onError: function () { } // 当值发生错误时(不符合验证时),调用方法
    }, options);


    this.child = [];
    this.valueData = null;
    this.value = null;
    this.cache = null;
    this.errorMessage = null;
    this.html = $('<div class="form_radio"></div>');
    if (this.options.data.length != 0) {
        this.setData(this.options.data);
    };

    // 事件集合
    this.event = {
        change: this.options.onChange,
        error: this.options.onError
    };

    // 存在模板对象,直接输出元素
    if (this.layout) {
        this.layout.append(this.html);
    };
};

radio.prototype.on = function (str, event) {
    if (this.event.hasOwnProperty(str)) {
        this.event[str] = event;
    };
    return this;
};

// 单独绑定 change 方法
radio.prototype.onChange = function (event) {
    this.event.change = event;
    return this;
};

// 单独绑定 error 方法
radio.prototype.onError = function (event) {
    this.event.error = event;
    return this;
};

// 遍历子对象方法
radio.prototype.eachChild = function (event) {
    for (var i = 0; i < this.child.length; i++) {
        var element = this.child[i];
        event(element);
    };
    return this;
};
radio.prototype.readonly = function (isReadonly) {
    var _isReadonly = null;
    if (verify.is(isReadonly) == 'function') {
        _isReadonly = isReadonly();
    };
    _isReadonly = !!isReadonly;
    var _this = this;
    if (isReadonly) {
        this.eachChild(function (child) {
            child.html.unbind('click');
        });
    } else {
        this.eachChild(function (child) {
            child.html.unbind().bind('click', function () {
                _this.change(child);
            });
        });
    };
};

radio.prototype.setData = function (data) {
    var _this = this;
    var dataType = verify.is(data);
    this.child = [];
    // 让select 支持 'optionSide:sex' 方式进行赋值
    if (dataType == 'string') {
        this.readonly(true);
        var optionsName = data.split(':');
        if (optionsName[1] && optionsName[0] == 'OptionSide') {
            this.html.text('加载中...');
            optionSide.get(optionsName[1], function (result) {
                _this.html.empty();
                _this.setData(result)
                if (_this.cache || _this.cache == 0) {
                    _this.set(_this.cache);
                    _this.cache = null;
                } else {
                    _this.defaultValue();
                };
                _this.readonly(_this.options.readonly);
            }, 'list');
        };
    } else if (dataType == 'array') {
        this.child = [];
        this.valueData = null;
        this.options.data = data;
        for (var i = 0; i < data.length; i++) {
            var item = data[i];
            var child = new radioItem(this.options.showKey, item, this);
            this.child.push(child);
            this.html.append(child.html);
        };
        this.defaultValue().readonly(this.options.readonly);
    };
    return this;
};

// 清除选择方法
radio.prototype.clear = function () {
    this.valueData = null;
    this.value = null;
    this.eachChild(function (child) {
        child.unSelect();
    });
    return this;
};
// 赋值方法
radio.prototype.set = function (data) {
    if (data === null) {
        this.clear();
    } else {
        var isComplete = false;
        var dataType = verify.is(data);
        if (dataType == 'array') {
            this.clear();
            this.setData(data);
            isComplete = true;
        } else {
            if (this.child.length === 0) {
                this.cache = data;
                isComplete = true;
            } else {
                var _this = this;
                if (dataType == 'string') {
                    this.clear().eachChild(function (clild) {
                        if (data == clild.data[_this.options.showKey]) {
                            _this.select(clild);
                            isComplete = true;
                        };
                    });
                } else if (dataType == 'object') {
                    this.clear().eachChild(function (clild) {
                        if (verify.isEqual(clild.data, data)) {
                            _this.select(clild);
                        };
                    });
                    isComplete = true;
                } else if (dataType == 'number') {
                    if (this.child[data]) {
                        this.clear();
                        _this.select(this.child[data]);
                        isComplete = true;
                    };
                };
            };
        };
        if (!isComplete) {
            console.error('select => set 错误 : 未找到指定的值');
        };
    };
    return this;
};

// 赋予默认值方法
radio.prototype.defaultValue = function () {
    if (this.options['default'] === null) {
        this.clear();
    } else {
        this.set(this.options['default']);
    };
    return this;
};

// 验证方法
radio.prototype.verify = function () {
    if (this.options.getKey != 'object') {
        var text = rules(this.options.verify, this.value);
        if (this.layout) {
            if (text) {
                this.event.error.apply(this, [text, this.html.val()]);
                this.layout.showError(text);
                this.errorMessage = text;
            } else {
                this.layout.hideError();
                this.errorMessage = null;
            }
        } else {
            // 如果错误信息不为空,则触发error方法,并保留错误信息
            if (text) {
                this.event.error.apply(this, [text, this.value]);
                this.errorMessage = text;
            } else {
                // 如果错误信息为空,侧清空错误信息
                this.errorMessage = null;
            };
        };
    };
    return this;
};

// 选中方法
radio.prototype.select = function (childObject) {
    this.valueData = childObject.data;
    if (this.options.getKey == 'object') {
        this.value = this.valueData;
    } else if (this.options.getKey == 'setKey') {
        this.value = this.valueData[this.options.setKey];
    } else if (this.valueData.hasOwnProperty(this.options.getKey)) {
        this.value = this.valueData[this.options.getKey];
    } else {
        console.log('select => select 错误 : 错误的取值类型');
    };
    childObject.select();
    return this;
};

// 当元素改变时触发事件
radio.prototype.change = function (childObject) {
    this.clear().select(childObject);
    this.event.change.apply(this, [this.value]);
    this.verify();
    return this;
};


// 取值方法
radio.prototype.get = function (callBack, ignore) {
    if (ignore) {
        callBack(this.value);
    } else {
        this.verify();
        if (this.errorMessage) {
            callBack(this.errorMessage);
        } else {
            callBack(false, this.value);
        };
    };
    return this;
};



export { radio };




